package com.glsc.ngateway.oaflow.service.xirtrade.enums;

import com.glsc.ngateway.common.xir.domain.*;
import com.glsc.ngateway.common.base.exception.PlatformException;

import cn.hutool.core.collection.CollectionUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.lang.Nullable;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import com.google.common.base.Joiner;

/**
 * 衡泰交易指令业务类型
 *
 * @author xuchang
 */
@Getter
@AllArgsConstructor
public enum 衡泰业务类型枚举_资金运营部 {
    同业拆借_拆入_首期("42", "同业拆借—拆入-首期", (iblb, party, trade) -> ((Objects.nonNull(party) && StringUtils.isNotBlank(party.getPartyname())) ? party.getPartyname() : Strings.EMPTY) + "拆入首期" + (Strings.isNotBlank(trade.getSetdate()) ? trade.getSetdate() : Strings.EMPTY) + ((Objects.nonNull(iblb) && StringUtils.isNotBlank(iblb.getEndsetdate())) ? ("(" + iblb.getEndsetdate() + "到期)") : Strings.EMPTY), (trade, iblb, party, ttrdOtcPledgebond, tbnd) -> null,
            //金额：本金
            iblb -> Objects.nonNull(iblb) ? new BigDecimal(iblb.getAmount()) : null),
    同业拆借_拆入_到期还款("42_END", "同业拆借-拆入-到期还款", (iblb, party, trade) -> ((Objects.nonNull(party) && StringUtils.isNotBlank(party.getPartyname())) ? party.getPartyname() : Strings.EMPTY) + "拆借还款" + ((Objects.nonNull(iblb) && StringUtils.isNotBlank(iblb.getEndsetdate())) ? iblb.getEndsetdate() : Strings.EMPTY), (trade, iblb, party, ttrdOtcPledgebond, tbnd) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(StringUtils.isNotBlank(trade.getPartyAccName()) ? ("资金账户户名：" + trade.getPartyAccName()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankAccName()) ? ("，资金开户行：" + trade.getPartyBankAccName()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankAccCode()) ? ("，资金账号：" + trade.getPartyBankAccCode()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankCode()) ? ("，支付系统行号：" + trade.getPartyBankCode()) : Strings.EMPTY);
        return sb.length() == 0 ? Strings.EMPTY : ("备注：国联证券拆借还款，" + sb);
    },
            //金额：本金+利息
            iblb -> Objects.nonNull(iblb) ? new BigDecimal(iblb.getAmount()).add(new BigDecimal(iblb.getAiamount())) : null),
    债券认购_分销买入_首期("61", "债券认购-分销买入-首期", (iblb, party, trade) -> ((Objects.nonNull(party) && StringUtils.isNotBlank(party.getPartyname())) ? party.getPartyname() : Strings.EMPTY) + "存单一级缴款" + ((Objects.nonNull(trade) && Strings.isNotBlank(trade.getSetdate())) ? trade.getSetdate() : Strings.EMPTY), (trade, iblb, party, ttrdOtcPledgebond, tbnd) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(StringUtils.isNotBlank(trade.getPartyAccName()) ? ("收款人账户名称：" + trade.getPartyAccName()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankAccName()) ? ("，收款人账号：" + trade.getPartyBankAccCode()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankAccCode()) ? ("，汇入行名称：" + trade.getPartyBankAccName()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankCode()) ? ("，支付系统清算行行号：" + trade.getPartyBankCode()) : Strings.EMPTY);
        return sb.length() == 0 ? Strings.EMPTY : "备注：国联证券存单缴款，" + sb;
    }, iblb -> null),

    /**
     * 目前分销买入首期和到期同时出现，无需关注到期执行
     */
    债券认购_分销买入_到期执行("61_END", "债券认购-分销买入-到期执行", (iblb, party, trade) -> ((Objects.nonNull(party) && StringUtils.isNotBlank(party.getPartyname())) ? party.getPartyname() : Strings.EMPTY) + "存单一级缴款" + ((Objects.nonNull(trade) && Strings.isNotBlank(trade.getSetdate())) ? trade.getSetdate() : Strings.EMPTY), (trade, iblb, party, ttrdOtcPledgebond, tbnd) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(StringUtils.isNotBlank(trade.getPartyAccName()) ? ("收款人账户名称：" + trade.getPartyAccName()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankAccName()) ? ("，收款人账号：" + trade.getPartyBankAccName()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankAccCode()) ? ("，汇入行名称：" + trade.getPartyBankAccCode()) : Strings.EMPTY);
        sb.append(StringUtils.isNotBlank(trade.getPartyBankCode()) ? ("，支付系统清算行行号：" + trade.getPartyBankCode()) : Strings.EMPTY);
        return sb.length() == 0 ? Strings.EMPTY : "备注：国联证券存单缴款，" + sb;
    }, iblb -> null),

    逆回购_首期("41",
            "逆回购_首期",
            (iblb, party, trade) ->
                    ((Objects.nonNull(party) && StringUtils.isNotBlank(party.getPartyname())) ? party.getPartyname() : Strings.EMPTY) +
                            "交易对手豁免申请" +
                            ((Objects.nonNull(trade) && Strings.isNotBlank(trade.getSetdate())) ? trade.getSetdate() : Strings.EMPTY),
            (trade, iblb, party, ttrdOtcPledgebond, tbnd) -> {
                StringBuilder sb = new StringBuilder("");
                if(Objects.nonNull(party) && StringUtils.isNotBlank(party.getPartyname())){
                    sb.append(party.getPartyname());
                }
                sb.append("交易对手豁免申请");
                if(Objects.nonNull(trade) && Strings.isNotBlank(trade.getSetdate())){
                    sb.append(trade.getSetdate());
                }
                if(Objects.nonNull(trade) && StringUtils.isNotBlank(trade.getRemark())){
                    sb.append(" " + trade.getRemark() + " ");
                }
                if (CollectionUtil.isNotEmpty(ttrdOtcPledgebond)) {
                    for(TtrdOtcPledgebond b:ttrdOtcPledgebond){
                        sb.append(" 折价率：" + b.getDiscount() + ",");
                    }
                }
                if (CollectionUtil.isNotEmpty(tbnd)) {
                    for (Tbnd d : tbnd) {
                        sb.append(" <br>债券代码：" + d.getICode() + " , 债券名称:" + d.getBName() + ",");
                    }
                }
                return sb.toString();
        //        sb.append(StringUtils.isNotBlank(trade.getPartyAccName()) ? (trade.getPartyAccName()) : Strings.EMPTY);
        //        sb.append((Objects.nonNull(party) && StringUtils.isNotBlank(party.getPartyname())) ? party.getPartyname() : Strings.EMPTY);
        //        sb.append(StringUtils.isNotBlank(trade.getPartyAccName()) ? (" 借：" + iblb.getTerm() + "d " + new BigDecimal(iblb.getRate()).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP) + "%") : Strings.EMPTY);
        //        sb.append(StringUtils.isNotBlank(trade.getPartyAccName()) ? (" 结算" + iblb.getAmount()) : Strings.EMPTY);
                //sb.append((Objects.nonNull(ttrdOtcPledgebond) ? (" " + ttrdOtcPledgebond.getPICode()) : Strings.EMPTY));
                //sb.append((CollectionUtil.isNotEmpty(tbnd)) ? (" " + Joiner.on(",").join(tbnd)) : Strings.EMPTY);
                //sb.append((Objects.nonNull(ttrdOtcPledgebond) ? (" " + ttrdOtcPledgebond.getParvalue()) : Strings.EMPTY));
                //sb.append((Objects.nonNull(ttrdOtcPledgebond) ? (" " + ttrdOtcPledgebond.getDiscount().multiply(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP) + "%") : Strings.EMPTY));
        //        return sb.length() == 0 ? Strings.EMPTY : sb + (StringUtils.isEmpty(trade.getRemark()) ? Strings.EMPTY : trade.getRemark());
            },
            iblb -> Objects.nonNull(iblb) ? new BigDecimal(iblb.getAmount()) : null),
    ;

    /**
     * 编码
     */
    private final String code;
    /**
     * 描述
     */
    private final String desc;

    /**
     * oa流程title构建方法
     */
    private TitleBuild titleBuilder;

    /**
     * oa流程划款说明构建方法
     */
    private HksmBuild hksmBuilder;
    /**
     * 计算交易金额
     */
    private ChangeAmountBuild changeAmountBuild;

    public static 衡泰业务类型枚举_资金运营部 seek(String code) {
        return Arrays.stream(衡泰业务类型枚举_资金运营部.values()).filter(o -> o.getCode().equals(code)).findFirst().orElseThrow(() -> PlatformException.error(String.format("未找到类型:%s", code)));
    }

    public static List<String> all() {
        return Arrays.stream(衡泰业务类型枚举_资金运营部.values()).map(衡泰业务类型枚举_资金运营部::getCode).collect(Collectors.toList());
    }

    public String getTitle(@Nullable TtrdOtcIblb iblb, @NotNull TtrdOtcCounterparty party, @NotNull TtrdOtcTrade trade) {
        return this.getTitleBuilder().build(iblb, party, trade);
    }

    public String getHksm(@NotNull TtrdOtcTrade trade, @Nullable TtrdOtcIblb iblb, @Nullable TtrdOtcCounterparty party, List<TtrdOtcPledgebond> ttrdOtcPledgebond, List<Tbnd> tbnd) {
        return this.getHksmBuilder().build(trade, iblb, party, ttrdOtcPledgebond, tbnd);
    }

    public BigDecimal countChangeAmount(@NotNull TtrdOtcIblb iblb) {
        return this.getChangeAmountBuild().build(iblb);
    }

    @FunctionalInterface
    private interface TitleBuild {
        String build(@Nullable TtrdOtcIblb iblb, @Nullable TtrdOtcCounterparty party, @Nullable TtrdOtcTrade trade);
    }

    @FunctionalInterface
    private interface HksmBuild {
        String build(@NotNull TtrdOtcTrade trade, @Nullable TtrdOtcIblb iblb, @Nullable TtrdOtcCounterparty party, @Nullable List<TtrdOtcPledgebond> ttrdOtcPledgebond, @Nullable List<Tbnd> tbnd);
    }

    @FunctionalInterface
    private interface ChangeAmountBuild {
        BigDecimal build(@NotNull TtrdOtcIblb iblb);
    }
}
